package com.lh0811.forge.pserv.uacs.server.service.impl;

import com.lh0811.forge.dependency.basic_code.BeanHelper;
import com.lh0811.forge.dependency.basic_code.IdWorker;
import com.lh0811.forge.dependency.basic_code.encrypt.PwdUtil;
import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityTenant;
import com.lh0811.forge.dependency.security.core.model.entity.WechatUserInfo;
import com.lh0811.forge.dependency.security.core.token.TokenManager;
import com.lh0811.forge.pserv.basic.api.api.BizNoBaseApi;
import com.lh0811.forge.pserv.uacs.api.constant.UacsContant;
import com.lh0811.forge.pserv.uacs.api.param.*;
import com.lh0811.forge.pserv.uacs.api.vo.CurrentUacsUserInfoVo;
import com.lh0811.forge.pserv.uacs.server.config.auth.VerificationHandler;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateUserDao;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateUserWechatInfoDao;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateUser;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateUserWechatInfo;
import com.lh0811.forge.pserv.uacs.server.service.CurrentUserService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
public class CurrentUserServiceImpl implements CurrentUserService {

    @Resource
    private UacsPlateUserWechatInfoDao uacsPlateUserWechatInfoDao;

    @Resource
    private UacsPlateUserDao uacsPlateUserDao;

    @Resource
    private BizNoBaseApi bizNoBaseApi;

    @Resource
    private VerificationHandler verificationHandler;

    @Resource
    private TokenManager tokenManager;


    @Override
    public void plateUserRegister(UacsPlateUserRegisterParam param) throws Exception {
        if (!StringUtils.equals(param.getPassword(), param.getRepwd())) {
            throw CommonException.create(ServerResponse.createByError("两次输入密码不一致"));
        }

        if (uacsPlateUserDao.lambdaQuery().eq(UacsPlateUser::getPhone, param.getPhone()).exists()) {
            throw CommonException.create(ServerResponse.createByError("手机号已存在"));
        }

        UacsPlateUser uacsPlateUser = new UacsPlateUser();
        uacsPlateUser.setId(IdWorker.nextId()); // 主键
        uacsPlateUser.setPlateUserNo(bizNoBaseApi.getNextNumByBizType(UacsContant.BizNoType.平台用户编号.getBizType())); // 平台用户编号
        uacsPlateUser.setNickName(param.getNickName()); // 昵称
        uacsPlateUser.setPhone(param.getPhone()); // 手机号
        String gensalt = PwdUtil.gensalt();
        String pwd = PwdUtil.hashPassword(param.getPassword(), gensalt);
        uacsPlateUser.setPassword(pwd); // 密码
        uacsPlateUser.setSalt(gensalt); // 密码盐
        uacsPlateUser.setBirthday(param.getBirthday()); // 生日
        uacsPlateUser.setGender(param.getGender()); // 性别： 00-保密 01-男 02-女
        uacsPlateUser.setRealNameFlag(Boolean.FALSE); // 是否实名认证
        uacsPlateUser.setLastLoginTime(new Date()); // 最后一次登录时间
        uacsPlateUser.setActiveFlag(Boolean.TRUE); // 是否可用
        uacsPlateUser.setWriteOffFlag(Boolean.FALSE); // 是否注销
        uacsPlateUser.setCreateTime(new Date()); // 创建时间
        uacsPlateUser.setCreateBy(uacsPlateUser.getId()); // 创建人
        uacsPlateUserDao.save(uacsPlateUser);
    }

    @Override
    public CurrentUacsUserInfoVo getCurrentUserInfo() throws Exception {
        // 获取当前登录用户
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户信息不存在"));
        }
        CurrentUacsUserInfoVo currentUacsUserInfoVo = BeanHelper.copyBean(uacsPlateUser, CurrentUacsUserInfoVo.class);
        currentUacsUserInfoVo.setCurrTenantId(securityAuthority.getSecurityUser().getCurrTenantInfo().getId());
        currentUacsUserInfoVo.setCurrTenantName(securityAuthority.getSecurityUser().getCurrTenantInfo().getTenantName());
        for (SecurityTenant securityTenant : securityAuthority.getSecurityUser().getTenantInfo()) {
            currentUacsUserInfoVo.getTenantInfoList().add(new CurrentUacsUserInfoVo.TenantInfo(securityTenant.getId(), securityTenant.getTenantName()));
        }
        return currentUacsUserInfoVo;
    }

    @Override
    public void changeTenantInfo(Long tenantId) throws Exception {
        // 获取当前登录用户
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();

        long count = securityAuthority.getSecurityUser().getTenantInfo().stream().filter(ele -> ele.getId().equals(tenantId)).count();
        if (count == 0) {
            throw CommonException.create(ServerResponse.createByError("非法操作！"));
        }

        // 更新用户默认租户
        uacsPlateUserDao.lambdaUpdate()
                .set(UacsPlateUser::getDefaultTenantId, tenantId)
                .set(UacsPlateUser::getUpdateTime, new Date())
                .eq(UacsPlateUser::getId, Long.valueOf(securityAuthority.getUserId()))
                .update();

        // 获取最新的用户信息
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));

        // 重新获取权限信息
        SecurityAuthority securityAuthorityNew = verificationHandler.genSecurityAuthority(uacsPlateUser);
        securityAuthorityNew.setClientType(securityAuthority.getClientType());
        securityAuthorityNew.setToken(securityAuthority.getToken());

        // 保存新的权限信息
        tokenManager.saveToken(securityAuthority.getToken(), securityAuthorityNew);
    }


    // 补充平台用户信息
    @Override
    public void fillPlateUserInfo(UacsPlateUserFillInfoParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户信息不存在"));
        }
        UacsPlateUser updateInfo = BeanHelper.copyBean(param, UacsPlateUser.class);
        updateInfo.setUpdateTime(new Date());
        updateInfo.setUpdateBy(uacsPlateUser.getId());
        uacsPlateUserDao.updateById(updateInfo);
    }

    // （通过微信平台API）补充用户信息
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void wechatUserReplenishUserInfo(PlateUserWechatInfoReplenishInfoParam param) throws Exception {
        // 获取当前用户
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();

        if (ObjectUtils.isEmpty(securityAuthority.getSecurityUser().getExtInfo().getJSONObject("weChatUserInfo"))) {
            throw CommonException.create(ServerResponse.createByError("微信用户信息不存在"));
        }
        WechatUserInfo weChatUserInfo = securityAuthority.getSecurityUser().getExtInfo().getObject("weChatUserInfo", WechatUserInfo.class);
        // 更新微信用户信息
        uacsPlateUserWechatInfoDao.lambdaUpdate()
                .set(UacsPlateUserWechatInfo::getUpdateBy, Long.valueOf(securityAuthority.getUserId()))
                .set(UacsPlateUserWechatInfo::getUpdateTime, new Date())
                .set(StringUtils.isNotBlank(param.getNickName()), UacsPlateUserWechatInfo::getNickName, param.getNickName())
                .set(StringUtils.isNotBlank(param.getGender()), UacsPlateUserWechatInfo::getGender, param.getGender())
                .set(StringUtils.isNotBlank(param.getLanguage()), UacsPlateUserWechatInfo::getLanguage, param.getLanguage())
                .set(StringUtils.isNotBlank(param.getCity()), UacsPlateUserWechatInfo::getCity, param.getCity())
                .set(StringUtils.isNotBlank(param.getProvince()), UacsPlateUserWechatInfo::getProvince, param.getProvince())
                .set(StringUtils.isNotBlank(param.getCountry()), UacsPlateUserWechatInfo::getCountry, param.getCountry())
                .set(StringUtils.isNotBlank(param.getAvatarUrl()), UacsPlateUserWechatInfo::getAvatarUrl, param.getAvatarUrl())
                .eq(UacsPlateUserWechatInfo::getId, weChatUserInfo.getId())
                .update();
        // 更新系统用户信息
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        UacsPlateUser updateInfo = new UacsPlateUser();
        updateInfo.setId(uacsPlateUser.getId());
        updateInfo.setUpdateBy(uacsPlateUser.getId());
        updateInfo.setUpdateTime(new Date());
        if (StringUtils.isBlank(uacsPlateUser.getNickName())) {
            updateInfo.setNickName(param.getNickName());
        }
        if (StringUtils.isBlank(uacsPlateUser.getAvatarUrl())) {
            updateInfo.setAvatarUrl(param.getAvatarUrl());
        }
        uacsPlateUserDao.updateById(updateInfo);
    }

    // 用户实名认证
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void userRealNameAuthentication(UserRealNameAuthenticationParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(param.getUserId());
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户信息不存在"));
        }

        // todo liuhe 调用实名认证接口

        // 补充用户认证信息
        uacsPlateUserDao.lambdaUpdate()
                .set(UacsPlateUser::getRealNameFlag, Boolean.TRUE)
                .set(UacsPlateUser::getRealName, param.getRealName())
                .set(UacsPlateUser::getIdCardNo, param.getIdCardNo())
                .set(UacsPlateUser::getUpdateTime, new Date())
                .set(UacsPlateUser::getUpdateBy, Long.valueOf(securityAuthority.getUserId()))
                .eq(UacsPlateUser::getId, uacsPlateUser.getId())
                .update();
    }

    // 用户绑定手机号
    @Override
    public void userBuildingPhoneForCurrentUser(String phone) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("未获取到序号配置"));
        }
        UacsPlateUser plateUser = uacsPlateUserDao.lambdaQuery().eq(UacsPlateUser::getPhone, phone).one();
        if (ObjectUtils.isNotEmpty(plateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户手机号已存在"));
        }
        uacsPlateUserDao.lambdaUpdate()
                .set(UacsPlateUser::getPhone, phone)
                .set(UacsPlateUser::getUpdateBy, Long.valueOf(securityAuthority.getUserId()))
                .set(UacsPlateUser::getUpdateTime, new Date())
                .eq(UacsPlateUser::getId, uacsPlateUser.getId())
                .update();
    }

    // 判断用户是否绑定手机号
    @Override
    public Boolean checkUserBuildingPhone() throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户信息不存在"));
        }
        return ObjectUtils.isNotEmpty(uacsPlateUser.getPhone());
    }

    // 判断用户是否已经实名认证
    @Override
    public Boolean checkUserRealNameAuth() throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户信息不存在"));
        }
        return uacsPlateUser.getRealNameFlag();
    }


    @Override
    public void reSetPassword(ReSetPasswordParam param) throws Exception {
        // 获取当前用户
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        if (!StringUtils.equals(param.getNewPwd(), param.getReSurePwd())) {
            throw CommonException.create(ServerResponse.createByError("两次输入密码不一致!"));
        }
        UacsPlateUser uacsPlateUser = uacsPlateUserDao.getById(Long.valueOf(securityAuthority.getUserId()));
        if (ObjectUtils.isEmpty(uacsPlateUser)) {
            throw CommonException.create(ServerResponse.createByError("用户信息不存在!"));
        }
        if (!StringUtils.equals(PwdUtil.hashPassword(param.getOldPwd(), uacsPlateUser.getSalt()), uacsPlateUser.getPassword())) {
            throw CommonException.create(ServerResponse.createByError("旧密码错误!"));
        }
        uacsPlateUserDao.lambdaUpdate()
                .set(UacsPlateUser::getUpdateBy, Long.valueOf(securityAuthority.getUserId()))
                .set(UacsPlateUser::getUpdateTime, new Date())
                .set(UacsPlateUser::getPassword, PwdUtil.hashPassword(param.getNewPwd(), uacsPlateUser.getSalt()))
                .eq(UacsPlateUser::getId, uacsPlateUser.getId())
                .update();
    }


}
